package optimizer;

import simulator.Simulator;

public class OptimizerMultiCore
{
	Simulator simulator;
	Target target;
	
	Optimizer[] optimizers;
	int numCompleted;
	
	public OptimizerMultiCore(Simulator simulator, Target target) {
		this.simulator = simulator;
		this.target = target;
	}
	
	/**
	 * Run our main optimizer strategy across the number of threads specified
	 * For the number of attempts passed (spread across all threads)
	 */
	public Strategy run(int numThreads, int numAttempts, int maxTimeForEachTry) {
		numCompleted = 0;
		optimizers = new Optimizer[numThreads];
		Thread[] threads = new Thread[numThreads];
		
		// For each thread
		for(int i=0; i<numThreads; i++) {
			// Run an Optimizer object in a new thread
			optimizers[i] = new Optimizer(simulator, target, numAttempts / numThreads, maxTimeForEachTry);
			threads[i] = new Thread(optimizers[i]);
			
			threads[i].start();
		}
		
		Strategy fastestStrategy = null;
		
		// For every thread
		for(int i=0; i<numThreads; i++) {
			try {
				// Wait for the thread to finish)
				threads[i].join();
				
				// If it's fastest strategy was faster than our current fastest strategy
				// store it as the fastest strategy
				if(fastestStrategy == null) {
					fastestStrategy = optimizers[i].fastestStrategy;
				}
				else {
					if((optimizers[i].fastestStrategy != null) && optimizers[i].fastestStrategy.getTime() < fastestStrategy.getTime()) {
						fastestStrategy = optimizers[i].fastestStrategy;
					}
				}
			}
			catch (InterruptedException e) {
				// Issue in thread, doesn't really matter for us though.
				// It's less than ideal, but we can't recover anyway
			}
		}
		
		return fastestStrategy;
	}
}
